<?php
/**
 * Created by PhpStorm.
 * User: 游贤川
 * Date: 2021/5/25
 * Time: 8:15
 */

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\DrawUrl;
use App\Models\HelpList;
use App\Models\LeavingMessage;
use App\Models\Prize;
use App\Models\PrizeUser;
use App\Models\RcUser;
use App\Models\TryMessage;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Mockery\Exception;

class RcUserController extends Controller
{

    /**
     * 注册
     */
    public function AddUser(Request $request)
    {
        //验证
        $verify = [
            'open_id' => 'required',
        ];
        $regulation = [
            'code.required' => 'open_id必填',
        ];
        $validator = Validator::make($request->all(), $verify, $regulation);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $data = $request->input();
        $open_id = $data['open_id'];
        $user = RcUser::query()->where('open_id', $open_id)->first();
        if ($user) {
            return $this->success($user, '成功');
        }

        try {

            //拿到用户数据
            $user = $this->AppUser($open_id);
            if ($user->Return >= 0) {
                $result = json_decode($user->Result);
                //判断是否为新用户
                $new_user = $this->NewUser($open_id);
                if ($new_user->code != 200) {
                    return $this->error($new_user->msg);
                }
                //判断用户是否存在
                $user_data = [
                    'name' => $result->Nickname,
                    'open_id' => $result->FansID,
                    'head_img' => $result->Headimgurl,
                    'insert_time' => $new_user->data ?? 0,
                    'luck_sum' => 1
                ];
                $model = RcUser::query()->updateOrCreate(['open_id' => $data['open_id']], $user_data);
                return $this->success($model, '用户创建成功');
            } else {
                return $this->error($user->ReturnInfo);
            }

        } catch (Exception $exception) {
            Log::error('添加用户报错', [$exception->getMessage()]);
            return $this->error($exception->getMessage());
        }

    }


    public function AppUser($open_id)
    {

        $method = 'MALLIF.GetFansInfoByOpenId';
        $data = [
            'Platform' => 'YLAMXForClient_SmallPragram',
            'OpenId' => $open_id
        ];

        $user = $this->Transfer($method, $data);
        return $user;

    }

    public function Transfer($method, $data = '')
    {
        $AuthKey = $this->Login();
        $params = ['RequestPack' => json_encode([
            'Method' => $method,
            'AuthKey' => $AuthKey,
            'Params' => json_encode($data),
        ])];
        $client = new Client(['base_uri' => 'https://club.yili.com/MALLIF_ThirdPublic/MCSWSIAPI.asmx/Call', 'timeout' => 5.0,]);
        $response = $client->post('', ['form_params' => $params]);
        $data = $response->getBody()->getContents();
        $xmlsting = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        $xml_json = json_decode($xmlsting);
        Log::info('调取接口详细记录', [$method, $AuthKey, $data, $xml_json]);
        return $xml_json;
    }

    public function Login()
    {
        $method = 'MALLIF.Login';

        $data = [
            'UserName' => 'amxforfeiyang',
            'Password' => 'fy2021amx!@',
            'DeviceCode' => 'DESKTOP'
        ];
        $user = $this->Transfer2($method, $data);
        return json_decode($user->Result)->AuthKey;

    }

    /**
     * 抽奖接口
     */
    public function LuckDraw(Request $request)
    {
        //验证
        $verify = [
            'open_id' => 'required|exists:App\Models\RcUser,open_id'
        ];
        $regulation = [
            'open_id.required' => 'open_id必填',
            'open_id.exists' => '未知用户'

        ];
//
        $validator = Validator::make($request->all(), $verify, $regulation);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $start = 1;
        $data = $request->input();
        $open_id = $data['open_id'];
        //开启事务
        try {
            DB::beginTransaction();

//            $sta_time = Carbon::now()->startOfDay();
//            $end_time = Carbon::now()->endOfDay();
//            $now_user_count = PrizeUser::query()
//                ->where(['user_openid' => $data['open_id']])
//                ->whereBetween('created_at',[$sta_time,$end_time])
//                ->count();
//            if ($now_user_count >= 10){
//                return $this->error('今天抽奖次数已达上限，请明天再来哦~~');
//            }
            $user = RcUser::query()->where(['open_id' => $open_id])->select(['name', 'luck_sum'])->lockForUpdate()->first();
            if (!$user) {
                return $this->error('用户不存在');
            }
            if ($user->luck_sum < 1) {
                return $this->error('抽奖次数不足');
            }
            //查找用户中奖数据
            $prize_data = PrizeUser::query()->where('user_openid', $open_id)->get();
            //只能中一次的奖品
            $type_1 = $prize_data->whereIn('type', [1, 2, 3, 8, 9])->pluck('type')->toArray();

            //中2次的奖品
            $type_2 = $prize_data->whereIn('type', 4)->count();
            if ($type_2 >= 2) {
                array_push($type_1, '4');
            }
            $type_3 = $prize_data->whereIn('type', 5)->count();
            if ($type_3 >= 2) {
                array_push($type_1, '5');
            }
            $type_3 = $prize_data->whereIn('type', 6)->count();
            if ($type_3 >= 1) {
                array_push($type_1, '6');
            }
            //得到所有奖品数量不为0的奖品
            $drawList = Prize::query()->whereNotIn('type', $type_1)->whereRaw('sum > winners_num')->lockForUpdate()->get();
            //判断还有没有奖品
            $drawList_count = $drawList->count();
            if ($drawList_count == 0) {
                return $this->error('今日奖品已领完，请明日再来！');
            }
            RcUser::query()->where(['open_id' => $open_id])->decrement('luck_sum', 1);
            //得到所有概率之和
            $drawRate = $drawList->sum('probability');
            //随机抽取奖品
            $luck = mt_rand($start, $drawRate);
            //查看是抽中的几号商品
            foreach ($drawList as $draw) {
                if (!empty($draw['probability'])) {
                    if ($luck >= $start && $luck <= $start + $draw['probability'] - 1) {
                        $draw_id = $draw['id'];
                        $draw_type = $draw['type'];
                        $money = $draw['money'];
                        $status = $draw['status'];
                        break;
                    }
                    $start += $draw['probability'];
                }
            }
            //奖品中奖数量+1
            Prize::query()->where(['id' => $draw_id])->increment('winners_num');
            //添加中奖数据
            $data = [
                'user_openid' => $open_id,
                'prize_id' => $draw_id,
                'type' => $draw_type,
                'prize_status' => $status
            ];
            //添加中奖记录
            $model = PrizeUser::query()->create($data);
            if ($status == 1) {
                $sign = $this->CreateSign($draw->code, $model->id, $open_id);
                $model -> sign = json_encode($sign);
                $model->save();
            }
            if ($status == 2){
                $model -> payment_no = $draw->code;
                $model->save();
            }
            DB::commit();
            return $this->success($draw, '成功');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('抽奖错误', [$e->getMessage()]);
            return $this->error('抽奖失败, ' . $e->getMessage());
        }
    }


    /**
     * 用户是否为新用户
     */

    public function NewUser($open_id)
    {

        $time = '2021-07-29 16:00:00';
        $client = new Client(['base_uri' => 'https://amxshop.yili.com/api/user/isNewMember?openId=' . $open_id . '&time=' . $time . '', 'timeout' => 5.0,]);
        $response = $client->get('');
        $data = $response->getBody()->getContents();
        return json_decode($data);

    }

    /**
     * 中奖列表
     */

    public function PrizeUser(Request $request)
    {
        $open_id = $request->input('open_id');
        $models = PrizeUser::query()->with(['prize'])->where(['user_openid' => $open_id])->get()->toArray();
        $list = [];
        foreach ($models as $k => $v) {
            $list[$k]['prize_user_id'] = $v['id'];
            $list[$k]['prize'] = $v['prize']['name'];
            $list[$k]['status'] = $v['status'];
            $list[$k]['time'] = date('m-d H:i', strtotime($v['created_at']));
            $list[$k]['type'] = $v['type'];
            $list[$k]['prize_status'] = $v['prize']['status'];
            $list[$k]['sign'] = $v['sign'];
            $list[$k]['payment_no'] = $v['payment_no'];
        }
        return $this->success($list, '中奖列表');
    }


    /**
     * 奖品配置
     */

    public function Prize()
    {
        $list = Prize::query()->select(['name', 'img'])->get();
        return $this->success($list, '成功');
    }

    /**
     * 留资
     */

    public function LeavingMessage(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'open_id' => 'required',
            'prize_user_id' => 'required'
        ], [
            'open_id.required' => '用户open_id必填',
            'prize_user_id.required' => '奖品id必填'
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $data = $request->input();
        $data['user_openid'] = $data['open_id'];
        $message = LeavingMessage::query()->where(['user_openid' => $data['open_id'], 'prize_user_id' => $data['prize_user_id']])->exists();
        if ($message) {
            return $this->error('已留资');
        }
        $leaving = LeavingMessage::query()->create($data);
        if ($leaving) {
            PrizeUser::query()->where(['id' => $data['prize_user_id'], 'user_openid' => $data['open_id']])->update(['status' => 1]);
        }
        return $this->success($leaving, '成功');
    }

    /**
     * 添加邀请记录
     */

    public function AddParent(Request $request)
    {
        //验证
        $verify = [
            'open_id' => 'required|exists:App\Models\RcUser,open_id',
            'parent_openid' => 'required|exists:App\Models\RcUser,open_id',
        ];
        $regulation = [
            'open_id.required' => 'open_id必填',
            'parent_openid.required' => 'parent_openid必填',
        ];
        $validator = Validator::make($request->all(), $verify, $regulation);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $data = $request->input();
        if ($data['open_id'] == $data['parent_openid']){
            return  $this->error('不能自己邀请自己哟~');
        }
        try {
            DB::beginTransaction();
            $user = RcUser::query()->where(['open_id' => $data['open_id']])->first();
            if (!$user) {
                return $this->error('用户不存在');
            }
            //判断邀请人是否存在
            $parent_user = RcUser::query()->where(['open_id' => $data['parent_openid']])->lockForUpdate()->first();
            if (!$parent_user) {
                return $this->error('邀请人不存在');
            }
            if ($user->help_num >= 1){
                return $this->error('邀请失败，您已为好友助力过喽～');
            }
//            $prize_user = PrizeUser::query()->where(['user_openid' => $data['open_id']])->exists();
//            if ($prize_user) {
//                $this->error('邀请失败，只有新用户才有邀请资格哟～');
//            }
            $help = HelpList::query()->where(['user_openid' => $data['open_id']])->exists();
            if ($help) {

                return $this->error('邀请失败，您已为好友助力过喽～');
            }
//            $sta_time = Carbon::now()->startOfDay();
//            $end_time = Carbon::now()->endOfDay();
//            $now_parent_user_count = HelpList::query()
//                ->where(['parent_openid' => $data['parent_openid']])
//                ->whereBetween('created_at',[$sta_time,$end_time])
//                ->count();
//            if ($now_parent_user_count < 9){
//               );
                HelpList::query()->create([
                    'user_openid' => $user->open_id,
                    'parent_openid' => $data['parent_openid'],
                    'time'=>Carbon::now()->toDateTimeString()
                ]);
                //邀请人抽奖次数加1
                $luck_num = $user->insert_time?2:1;
                $parent_user->increment('luck_sum',$luck_num);
                $user->increment('luck_sum',$luck_num);
                RcUser::query()->where('open_id',$data['open_id'])->update(['help_num'=>1]);
//            }else{
//                return $this->error('今日邀请已达上限哦');
//            }

            DB::commit();
            return $this->success('', '邀请成功');
        }catch (\Exception $exception){
            DB::rollBack();
            Log::error('邀请失败',[$exception->getMessage()]);
            return  $this->error('邀请失败，您已为好友助力过喽～');
        }

    }


    public function TestWx()
    {
        $template = \App\Models\WxMessage::query()->first();
        $token = env('WX_TOKEN');
        $client = new Client(['', 'timeout' => 5.0,]);
        //拿到微信access_token
        $response1 = $client->get('https://amxshop.yili.com/api/user/getAccessToken', ['headers' => ['accessToken' => $token]]);
        $data = json_decode($response1->getBody()->getContents());
        $wx_token = $data->data;
        $wx_url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $wx_token;
        $data_str = explode('|', $template->data);
        $data = [];
        $data['thing1']['value'] = $data_str[0];
        $data['thing2']['value'] = $data_str[1];
        $data['thing4']['value'] = $data_str[2];
        $params = [
            'touser' => 'osgSC4vsW_uZWHXsyeqmIoNL2E_k',
            'template_id' => $template->template_id,
            'data' => $data
        ];
        $client = new Client(['', 'timeout' => 5.0,]);
        $response2 = $client->post($wx_url, ['json' => $params]);
//        $content = json_decode($response2->getBody()->getContents());
        dd(json_decode($response2->getBody()->getContents()));
    }

    /**
     * 测试签名
     * uuid-奖品uuid（客户自行定义奖品对应的uuid，同步给我方即可）
     * prizeordernum-订单
     * mopenid-用户在安慕希小程序/H5的openid
     * mtimestamp-时间戳
     * sign-签名
     *
     * 签名方式：(与兑奖接口保持一致)
     * 1，以上参数除sign外升序拼接成字符串后md5然后转成大写
     * 2，1得到的结果拼接密钥后md5然后转成大写
     * 升序拼接串：
     * exchangeTime=2021-05-31 15:33:33&orderId=cas21125&result=-1
     *
     * Demo：strtoupper(md5(strtoupper(md5(http_build_query($param))). $secret))
     */

    public function CreateSign($uuid, $prizeordernum, $mopenid)
    {
        $mtimestamp = time();
        $secret = '5BaN8Xyo1XQ0qZFg';
        $param = [
            'mtimestamp' => $mtimestamp,
            'prizeordernum' => $prizeordernum,
            'uuid' => $uuid,
            'mopenid' => $mopenid
        ];
        ksort($param);
        $sign = strtoupper(md5(strtoupper(md5(http_build_query($param))) . $secret));
        $param['sign'] = $sign;
        return $param;
    }

    /**
     * 修改用户中奖数据状态
     */

    public function UpdatePrizeUser(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'mopenid' => 'required|exists:App\Models\RcUser,open_id',
            'prizeordernum' => 'required',
            'mtimestamp' => 'required',
            'sign' => 'required'
        ], [
            'mopenid.required' => 'mopenid必填',
            'prizeordernum.required' => 'prizeordernum必填',
            'sign.required' => 'sign必填',
            'mtimestamp.required' => 'mtimestamp必填'
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $data = $request->input();
        $param = [
            'mtimestamp' => $data['mtimestamp'],
            'prizeordernum' => $data['prizeordernum'],
            'mopenid' => $data['mopenid']
        ];
        ksort($param);
        $secret = '5BaN8Xyo1XQ0qZFg';
        $sign = strtoupper(md5(strtoupper(md5(http_build_query($param))) . $secret));
        if (!($sign == $data['sign'])) {
            Log::info('道具领取回调错误',[$data]);
            return $this->json($data, 400, 'sign不匹配');
        }
        $prize_user = PrizeUser::query()->where(['user_openid' => $data['mopenid'], 'id' => $data['prizeordernum']])->first();
        if (!$prize_user) {
            return $this->error('数据不存在');
        }
        Log::info('道具领取成功回调',[$data]);
        if ($prize_user->status == 1) {
            return $this->error('已领奖');
        }
        $prize_user->update(['status' => 1]);
        return $this->success('', '成功');
    }

    public function Transfer2($method, $data = '', $AuthKey = '')
    {
        $params = ['RequestPack' => json_encode([
            'Method' => $method,
            'AuthKey' => $AuthKey,
            'Params' => json_encode($data),
        ])];
        $client = new Client(['base_uri' => 'https://club.yili.com/MALLIF_ThirdPublic/MCSWSIAPI.asmx/Call', 'timeout' => 5.0,]);
        $response = $client->post('', ['form_params' => $params]);
        $data = $response->getBody()->getContents();
        $xmlsting = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        $xml_json = json_decode($xmlsting);
        return $xml_json;
    }

    /**
     *轮播中奖记录
     */
    public function IndexPrize()
    {
        $Index_prize = PrizeUser::query()->select(['user_openid','prize_id'])->where('type','!=',7)->with('user:open_id,name,head_img')->with('prize:id,name')->orderByDesc('created_at')->limit(5)->get();
        return $this->success($Index_prize, '成功');
    }

    /**
     * 试吃
     */

    public function TryMessage(Request $request)
    {
        //验证
        $verify = [
            'open_id'=>'required',
            'type'=>'required'
        ];
        $regulation = [
            'open_id.required' => 'open_id必填',
            'type.required' => 'type必填',
        ];
        $validator = Validator::make($request->all(), $verify, $regulation);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $data = $request->input();
        try{
            switch ($data['type']){
                case 1:
                    $model = TryMessage::query()->where(['open_id'=>$data['open_id']])->first();
                    if ($model) return $this->error('已留资');
                    $data['uuid'] = strtoupper(uniqid());
                    $message = TryMessage::query()->updateOrCreate(['open_id'=>$data['open_id']],$data);
                    break;
                case 2:
                    $message = TryMessage::query()->updateOrCreate(['open_id'=>$data['open_id']],$data);
                    break;
                case 3:
                    $model = TryMessage::query()->where(['open_id'=>$data['open_id']])->first();
                    if ($model->img || $model->evaluate){
                        return $this->error('您已填写过试吃评价，请耐心等待审核');
                    }
                    $message = TryMessage::query()->updateOrCreate(['open_id'=>$data['open_id']],$data);
                    break;
                default:
                    return $this->error('参数错误');
            }
            return $this->success($message,'成功');
        }catch (\Exception $exception){
            Log::error('试吃错误',[$data]);
            $this->error($exception->getMessage());
        }

    }


    public function UpdateStatus(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'open_id' => 'required|exists:App\Models\RcUser,open_id',
            'prize_user_id' => 'required|exists:App\Models\PrizeUser,id',
        ], [
            'open_id.required' => 'open_id必填',
            'prize_user_id.required' => 'prize_user_id必填',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $data = $request->input();

        $model = PrizeUser::query()->where(['id'=>$data['prize_user_id'],'user_openid'=>$data['open_id']])->first();
        if (!$model){
            return  $this->error('奖品不存在');
        }
        $prize = $model->update(['status'=>1]);

        if (!$prize){
            return $this->error('领取错误');
        }
        return $this->success('成功');

    }


    public function UserTryMessage(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'open_id' => 'required',
        ], [
            'open_id.required' => 'open_id必填',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $open_id = $request->input('open_id');
        $user = TryMessage::query()->where('open_id',$open_id)->first();
        return $this->success($user,'成功');
    }

    public function DrawUrl()
    {
        $model = DrawUrl::query()->where('status',0)->get();
        if ($model->count()==0){
            return $this->error('已发完');
        }
        $url = $model->random(1);
        $url[0]->update(['status'=>1]);
        return $this->success($url,'成功');
    }

    public function store(Request $request)
    {
        $file = request()->file('file');
        if($file->isValid()){
            $ext = $file->getClientOriginalExtension();//文件扩展名
            $file_name = date("YmdHis",time()).'-'.uniqid().".".$ext;//保存的文件名
            if(!in_array($ext,['jpg','jpeg','gif','png']) ) return $this->error('图片上传失败');;
            //把临时文件移动到指定的位置，并重命名
            $path = public_path().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'wchat_img'.DIRECTORY_SEPARATOR.date('Y').DIRECTORY_SEPARATOR.date('m').DIRECTORY_SEPARATOR.date('d').DIRECTORY_SEPARATOR;
            $bool =  $file->move($path,$file_name);
            if($bool){
                $img_path = env('APP_URL').'/uploads/wchat_img/'.date('Y').'/'.date('m').'/'.date('d').'/'.$file_name;

                return $this->success($img_path);
            }else{
                return $this->error('图片上传失败');
            }
        }else{
            return $this->error('图片上传失败');
        }



    }


    public function userList(Request $request)
    {
//        $page_size = $request->post('page_size',15);
        $eat_message = $request->input('eat_type',0);
        $list = TryMessage::query()->where(['examine'=>1,'eat_type'=>$eat_message])->get();
        return $this->success($list,'成功');
    }

}
